home *** CD-ROM | disk | FTP | other *** search
- /*
- File: MailableWindow.cp
-
- Contains: A AOCE-aware window base class
-
- Written by: Dave Falkenburg with help from Steve Falkenburg’s
- CollaboDraw “object oriented C” sample application.
-
- Copyright: Copyright © 1993-1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 8/19/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1
- 9/27/94 DRF Changes for Dave Mark: AppLib.h is now Sprocket.h.
- 9/9/94 DRF Reordered headers and removed redundant #includes and
- conditionalize AOCE support.
- 8/26/94 DRF Added AdjustPerfectWindowSizeForMailer.
-
- */
-
- #include "Sprocket.h"
- #include "MailableWindow.h"
-
- #if qAOCEAware
-
- TMailableWindow::TMailableWindow()
- {
- // Remember, we can’t do anything in here because of C++’s insistance
- // of creating objects from the bottom-up. If we call CreateWindow in
- // here then we end up calling the pure-virtual version of MakeNewWindow.
-
- fMailerIsAttached = false;
- fMailerIsExpanded = false;
- }
-
-
- TMailableWindow::~TMailableWindow()
- {
- #if qDebug
- // Release any PowerTalk things if they are still around
-
- if (fMailerIsAttached)
- DebugStr("\pDidn’t call TMailableWindow::Close to dispose mailer");
- #endif
- }
-
-
- Boolean
- TMailableWindow::EventFilter(EventRecord * anEvent)
- {
- if (gHasAOCE)
- {
- SMPMailerResult whatHappened;
- SMPMailerState mailerState;
-
- (void) SMPMailerEvent(anEvent,&whatHappened,FrontWindowProcForAOCEUPP,0);
- (void) SMPGetMailerState(fWindow,&mailerState);
-
- // ALOT MORE STUFF GOES IN HERE!
-
- // track if the mailer has been expanded or contracted
- if ((whatHappened & kSMPContractedMask) != 0)
- this->ExpandOrContractMailer(false);
- else if ((whatHappened & kSMPExpandedMask) != 0)
- this->ExpandOrContractMailer(true);
-
- // check to see if the app must handle this event
- if ((whatHappened & kSMPAppMustHandleEventMask) != 0)
- return false;
- else
- return true; // nope, PowerTalk dealt with the event, we don’t have to.
- }
-
- return false;
- }
-
-
- void
- TMailableWindow::CreateWindow(WindowType typeOfWindowToCreate /* = kNormalWindow */)
- {
- #if qDebug
- // You can’t put a mailer in a floating window or a modal window!
-
- if (typeOfWindowToCreate != kNormalWindow)
- DebugStr("\pTMailableWindow: Must be normal windows");
- #endif
-
- TWindow::CreateWindow();
-
- if (gHasAOCE && gPreferences.fMailPreferences.fCreateMailerForNewDocuments)
- this->AttachMailerToWindow(true);
-
- fContentRect = fWindow->portRect;
- }
-
-
- Boolean
- TMailableWindow::Close(void)
- {
- Boolean reallyClosing = true;
-
- if (fMailerIsAttached)
- {
- // Offer to send or save the letter if it has changed
-
- }
- else
- {
- // Offer to save the document if it is dirty
-
- }
-
- if (fMailerIsAttached)
- {
- // We need to remove the mailer before calling TWindow::Close
- // otherwise AOCE will get very confused. Too bad they didn’t
- // integrate better with the window manager to catch this for us.
-
- this->RemoveMailerFromWindow();
- }
-
- if (reallyClosing)
- return TWindow::Close();
-
- return false;
- }
-
-
- OSErr
- TMailableWindow::AttachMailerToWindow(Boolean createExpanded)
- {
- Point where = {0,0};
- OSErr err;
-
- err = SMPNewMailer(fWindow,where,kCanContract,createExpanded,kDefaultAuthIdentity,nil,0L);
- fMailerIsAttached = (err == noErr);
- fMailerIsExpanded = kInitiallyExpanded;
-
- return err;
- }
-
-
- OSErr
- TMailableWindow::RemoveMailerFromWindow(void)
- {
- OSErr err = noErr;
- SMPCloseOptions closeOptions;
-
- closeOptions.moveToTrash = false;
- closeOptions.addTag = false;
- closeOptions.tag.dataLength = 0;
-
- if (fMailerIsAttached)
- {
- // Get rid of the PowerTalk mailer header
- err = SMPDisposeMailer(fWindow,&closeOptions);
-
- fMailerIsAttached = false;
- fContentRect = fWindow->portRect;
- }
-
- return err;
- }
-
-
- void
- TMailableWindow::Draw(void)
- {
- // Because of SMPMailerEvent, the PowerTalk mailer, if present will be drawn by AOCE
- // This means the window’s draw method only needs to worry drawing the other content
-
- RgnHandle originalClipRgn = NewRgn();
-
- GetClip(originalClipRgn);
- ClipRect(&fContentRect);
-
- // Possible optimization by checking content rect against visRgn
- // « we probably also want to do a wacky SetOrigin call here »
- this->DrawContents();
-
- SetClip(originalClipRgn);
- DisposeRgn(originalClipRgn);
- }
-
-
- void
- TMailableWindow::AdjustPerfectWindowSizeForMailer(Rect * perfectSize)
- {
- // If a mailer is attached to the window, figure out how big it is
- // and make sure that the window is wide enough to deal with it.
-
- if (fMailerIsAttached)
- {
- short expHeight,contHeight,mWidth;
-
- (void) SMPGetDimensions(&mWidth,&contHeight,&expHeight);
-
- // Make sure the perfect size is wide enough for the standard mailer.
-
- if (perfectSize->right < perfectSize->left + mWidth)
- perfectSize->right = perfectSize->left + mWidth;
-
- // We might also want to adjust height, but for now ignore the problem
- }
- }
-
-
- void
- TMailableWindow::AdjustForNewWindowSize(Rect * /* oldRect */,Rect * newRect)
- {
- // NOTE: Assumes rect is always zero-based
-
- fContentRect.bottom = newRect->bottom;
- fContentRect.right = newRect->right;
- }
-
-
- void
- TMailableWindow::ExpandOrContractMailer(Boolean doExpand)
- {
- GrafPtr oldPort;
- Rect prevContentRect, newContentRect;
- short expHeight,contHeight,mWidth;
-
- GetPort(&oldPort);
- SetPort(fWindow);
-
- (void) SMPGetDimensions(&mWidth,&contHeight,&expHeight);
-
- prevContentRect = fContentRect;
- newContentRect = fWindow->portRect;
-
- if (doExpand)
- newContentRect.top += expHeight;
- else
- newContentRect.top += contHeight;
-
- this->AdjustForNewContentRect(&prevContentRect,&newContentRect);
- fContentRect = newContentRect;
-
- (void) SMPExpandOrContract(fWindow,doExpand);
- fMailerIsExpanded = true;
-
- SetPort(oldPort);
- }
-
-
- void
- TMailableWindow::AdjustForNewContentRect(Rect * /* prevContentRect */,Rect * newContentRect)
- {
- // the default thing to do is to force a complete redraw of the window’s normal
- // content area. We could be clever and use scrollrect to keep the bits around,
- // but for now we cheeze out.
-
- InvalRect(newContentRect);
- }
-
- void
- TMailableWindow::DrawContents(void)
- {
- }
-
-
- // FrontWindow custom procedure for AOCE standard mail package:
- // It enables some of AOCE to cleanly interoperate with “Dean Yu”-style floating windows
-
- pascal WindowPtr
- FrontWindowProcForAOCE(long /* unusedParam */)
- {
- return MyFrontNonFloatingWindow();
- }
-
- FrontWindowUPP FrontWindowProcForAOCEUPP = NewFrontWindowProc(&FrontWindowProcForAOCE);
-
- #endif